﻿/**	@file		pretty_mesh.h
 *	@date		(2008-08-23 14:32:29)/(2009-09-04 00:46:54)
 *-----------------------------------------------------------------------------
 *	@version	1.0.7.11
 *	@author		Nick Shallery	(nicknide@gmail.com)
 *	@copyright	YOU HAVE ALL LEFT WITH THIS CODE WHILE YOU KEEP COMMENT IN EVERY COPY.
 *-----------------------------------------------------------------------------
**/

#if			!defined(__LXUT__MOD__PRETTY_MESH__NICK__K_IN_G__)
#define		__LXUT__MOD__PRETTY_MESH__NICK__K_IN_G__
//==============================================================================
//--------------------------------------------------------------------------

#if			!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)
	#include	"../../lolix/lolix_type.h"
#endif	//	!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)

#if			!defined(__LOLIX__PRETTY__CANVAS__K_IN_G__)
	#include	"../../lxpretty/canvas.h"
#endif	//	!defined(__LOLIX__PRETTY__CANVAS__K_IN_G__)

#if			!defined(__LXUT__RSRC__RSRC_POND__NICK__K_IN_G__)
	#include	"../rsrc/rsrc_pond.h"
#endif	//	!defined(__LXUT__RSRC__RSRC_POND__NICK__K_IN_G__)


namespace lxut{namespace mod{
	class	pretty_mesh;
}}


class LOLIX_NO_VTABLE	lxut::mod::pretty_mesh
	: public lolix::itf
{
protected:
	typedef	lolix::pretty::render_mesh	render_mesh;
	typedef	render_mesh::ENUM_VERTEX_TYPE ENUM_VERTEX_TYPE;
public:
	LOLIX_DECLARE_ITF(pretty_mesh, lolix::itf, (0xe944b6f5, 0xf9594b3f, 0x89260ce7, 0xe6ce0d01));
	class	rsrc_fetch_type;
	enum	ENUM_VTX_TYPE
	{	VTX_TYPE_VERTEX
	,	VTX_TYPE_TEXCOORD
	,	VTX_TYPE_NORMAL
	,	VTX_TYPE_TANGENT
	,	VTX_TYPE_COLOR
	,	_VTX_TYPE_CNT
	,	_VTX_TYPE_VER = 0
	};

	//===========================================================================
	//	设置属性行的值
	//---------------------------------------------------------------------------
	//	vtx_type		[i ]	属性类型
	//	val_type		[i ]	属性的值类型
	//	offset			[i ]	属性的起始从缓冲区的多少长度开始 (byte)
	//	stride			[i ]	每组属性之间间隔多少
	//	elm_size		[i ]	每组属性有多少个单元 [1, 4]
	//	in_data			[i ]	属性数据
	//	data_size		[i ]	属性数据的总长度(byte)
	//---------------------------------------------------------------------------
	//	返回值说明
	//---------------------------------------------------------------------------
	//	特别注释:	in_data 的值可以取真实物理地址， 也可以取 ENUM_VTX_TYPE 中的数据
	//				当 data 的数据为 ENUM_VTX_TYPE 具体类别时， 表示说这两个类型拥有
	//				相同的属性数据缓冲区， 此时， data_size 必须为 0
	//===========================================================================
	LOLIX_INTERFACE(set_att	, lolix::LOLIX_RETNV	, (ENUM_VTX_TYPE  in_vtx_type, lolix::ENUM_VALUE_TYPE in_val_type
													, size_type in_offset, size_type in_stride, size_type in_elm_size
													, const void* in_data, size_type in_data_size));

	//===========================================================================
	//	设置索引缓冲区内容
	//---------------------------------------------------------------------------
	//	vtx_type		[i ]	mesh 类型
	//	val_type		[i ]	索引数据的类型
	//	idx_byte_size	[i ]	索引的长度 : 字节数
	//	in_ptr			[i ]	索引缓冲区
	//===========================================================================
	LOLIX_INTERFACE(set_idx	, lolix::LOLIX_RETNV	, (ENUM_VERTEX_TYPE in_vtx_type, lolix::ENUM_VALUE_TYPE in_val_type
													, const void* in_ptr, size_type in_idx_byte_size));


	//===========================================================================
	//	申请一块内部内存
	//---------------------------------------------------------------------------
	//	ptr				[ o]	返回的内部内存首地址（没有对齐）
	//	len				[i ]	申请的地址长度
	//---------------------------------------------------------------------------
	//	#:	此时可以把返回的值作为 set_idx, set_att 里面的那个指针传递进去；
	//		同时， in_data_size 依旧必须为 0
	//===========================================================================
	LOLIX_INTERFACE(mapping	, lolix::LOLIX_RETNV	, (void** in_ptr, size_type in_len));

	//===========================================================================
	//	取消一个申请的内存
	//---------------------------------------------------------------------------
	//	ptr				[i ]	申请偿还的内存
	//---------------------------------------------------------------------------
	//	#:	使用 set 函数设置到内部的内存不需要调用这个值来返回了
	//===========================================================================
	LOLIX_INTERFACE(unmapping,	void				, (const void* in_ptr));

	//===========================================================================
	//	将一个 render_mesh 赋上当前属性
	//---------------------------------------------------------------------------
	//	rmesh			[io]	需要被设置的 rmesh
	//===========================================================================
	LOLIX_INTERFACE(ld_rm	, lolix::LOLIX_RETNV	, (render_mesh* io_rm)const);

	class	auto_unmapping;
};



class LOLIX_NO_VTABLE lxut::mod::pretty_mesh::rsrc_fetch_type
	: public lxut::rsrc::rsrc_fetch
{
public:
	LOLIX_DECLARE_ITF(rsrc_fetch_type, lxut::rsrc::rsrc_fetch, (0x2193b0af, 0xf3044e7b, 0x8ed82c05, 0xa23fbe63));
};


class	lxut::mod::pretty_mesh::auto_unmapping
{
	const void*	_ptr;
	pretty_mesh* _pm;
public:
	LOLIX_INLINE_CALL	auto_unmapping(void):_ptr(0){}
	LOLIX_INLINE_CALL	auto_unmapping(pretty_mesh* pm, const void* ptr):_pm(pm), _ptr(ptr){}
	LOLIX_INLINE_CALL	~auto_unmapping(void){__Clear();}
	LOLIX_INLINE_CALL	const void* release(void){ const void* ptr = _ptr; _ptr = 0; return ptr;}
	LOLIX_INLINE_CALL	void reset(void){__Clear();_ptr = 0;}
	LOLIX_INLINE_CALL	void reset(pretty_mesh* pm, const void* ptr){__Clear(); _pm = pm; _ptr = ptr; }
private:
	LOLIX_INLINE_CALL	void	__Clear(void){if (_ptr) _pm->unmapping(_ptr);}
};



//#define						PRETTY_MESH_FILTER_ID	(0xccda4c45, 0x89734ce8, 0xaa73b11e, 0x7abe6091)
//static const lolix::LOLIX_ITF_ID	pretty_mesh_filter_id	PRETTY_MESH_FILTER_ID;


//--------------------------------------------------------------------------
//==============================================================================
#endif	//	!defined(__LXUT__MOD__PRETTY_MESH__NICK__K_IN_G__)
